<template>
  <div ref="preview" class="pdf-preview" v-loading="_loading">
    <div class="page-tool">
      <div class="page-tool-item" @click="lastPage">上一页</div>
      <div class="page-tool-item pageBox">
        <el-input
          size="mini"
          v-model="state.pageNum"
          class="input"
          onkeyup="value=value.replace(/[^\d]/g,'')"
          @blur="inputChange"
          @keyup.enter="inputChange"
        ></el-input>
        <span class="mr5 ml5">/</span>
        <span>{{ state.numPages }}</span>
      </div>
      <div class="page-tool-item" @click="nextPage">下一页</div>
    </div>
    <div class="pdf-wrap">
      <div v-if="state.numPages > 50">
        <vue-pdf-embed
          :source="state.source"
          class="vue-pdf-embed"
          :page="currentNum"
          @loaded="loaded"
        />
      </div>
      <div v-else>
        <vue-pdf-embed
          :source="state.source"
          class="vue-pdf-embed"
          @loaded="loaded"
        />
      </div>
    </div>
    <el-empty
      v-if="isError"
      description="PDF文件预览失败，请检查文件路径是否正确"
    >
    </el-empty>
  </div>
</template>

<script setup>
import { createLoadingTask } from 'vue3-pdfjs/esm'
const VuePdfEmbed = defineAsyncComponent(() => import('vue-pdf-embed'))
const { proxy } = getCurrentInstance()
const props = defineProps({
  pdfUrl: {
    type: String,
    required: true,
  },
})
const state = reactive({
  source: props.pdfUrl, //预览pdf文件地址
  pageNum: 1, // 当前页面
  numPages: 0, // 总页数
})
// pdf预览是否成功
const isError = ref(false)
// 单页PDF的高度
const pdfHeight = ref(0)
// 滚动高度
const scrollTop = ref(0)
const currentNum = ref(1)
const loading = ref(true)
const loadNumPage = ref(true)

const _loading = computed(() => {
  return loading.value || loadNumPage.value
})
onMounted(() => {
  const loadingTask = createLoadingTask(state.source)
  loadingTask.promise
    .then((pdf) => {
      isError.value = false
      state.numPages = pdf.numPages
      loadNumPage.value = false
    })
    .catch((error) => {
      isError.value = true
      loading.value = false
      loadNumPage.value = false
    })
  //state.numPages = 268
  loadNumPage.value = false
  proxy.$refs['preview'].onscroll = () => {
    windowOnsconscroll()
  }
  document.oncontextmenu = function () {
    return false
  }
})

function windowOnsconscroll() {
  proxy.$nextTick(() => {
    scrollTop.value = proxy.$refs['preview'].scrollTop + 300
    pdfHeight.value = document.querySelector('.textLayer')
      ? document.querySelector('.textLayer').offsetHeight
      : 1128
    if (state.numPages < 50) {
      state.pageNum = Math.ceil(scrollTop.value / pdfHeight.value)
    }
  })
}
function lastPage() {
  state.pageNum = Number(state.pageNum)
  if (state.pageNum > 1) {
    state.pageNum -= 1
    currentNum.value = Number(state.pageNum)
    goPage()
  }
}
function nextPage() {
  state.pageNum = Number(state.pageNum)
  if (state.pageNum < state.numPages) {
    state.pageNum += 1
    currentNum.value = Number(state.pageNum)
    goPage()
  }
}
function inputChange() {
  if (state.pageNum <= 0) {
    state.pageNum = 1
  }
  if (state.pageNum > state.numPages) {
    state.pageNum = state.numPages
  }
  currentNum.value = Number(state.pageNum)
  goPage()
}
function loaded() {
  loading.value = false
}
function goPage() {
  pdfHeight.value = document.querySelector('.textLayer')
    ? document.querySelector('.textLayer').offsetHeight
    : 1128
  proxy.$refs['preview'].scrollTo(0, (state.pageNum - 1) * pdfHeight.value)
}
</script>
<style lang="scss" scoped>
.pdf-preview {
  height: 100%;
  padding: 10px 0;
  box-sizing: border-box;
  background-color: #e9e9e9;
  overflow: auto;
}
.pdf-wrap {
  margin: 0 auto;
  width: 900px;
  .vue-pdf-embed {
    text-align: center;
    border: 1px solid #e5e5e5;
    box-sizing: border-box;
  }
}
.pageBox {
  display: flex;
  align-items: center;
  .input :deep(.el-input__inner) {
    display: inline-block;
    text-align: center;
    height: 20px;
    line-height: 20px;
    width: 40px;
    padding: 0 4px;
  }
}
.page-tool-item {
  padding: 8px 15px;
  padding-left: 10px;
  cursor: pointer;
}

.page-tool {
  position: absolute;
  top: -49px;
  left: 50%;
  transform: translateX(-50%);
  padding-left: 15px;
  padding-right: 15px;
  display: flex;
  align-items: center;
  background: rgba(64, 158, 255, 0.8);
  color: white;
  border-radius: 19px;
  z-index: 100;
  cursor: pointer;
}
</style>
